package mcommand;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.util.ArrayList;

import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamWriter;

/**
 * An easy to use tool to write to XML files. Provides Highscore writing from
 * Lists and Level writing from EventLists.
 * 
 * @author Marcel, Christian, Klaus
 * 
 */
public class ToolXMLWriter {

    private static String highscorePath = "highscore.xml";
    private static String gameStatePath = "gamestate.xml";
    private static String statisticsPath = "statistics.xml";

    /**
     * writes highscore into a xml file (standard: "highscore.xml").
     *
     * @param playernames
     *            list of playernames written into highscore list file
     * @param scores
     *            list of scores written into highscore list file
     */
    public static void writeHighscore(final ArrayList<String> playernames,
            final ArrayList<Integer> scores) {
        XMLOutputFactory factory = XMLOutputFactory.newInstance();
        XMLStreamWriter document = null;

        if (Board.DEBUG) {
            System.out.println("XML Highscore (" + highscorePath
                    + ") wird geschrieben.");
        }

        try {
            document = factory.createXMLStreamWriter(new FileOutputStream(
                    highscorePath));

            document.writeStartDocument();

            document.writeStartElement("highscore");

            for (int i = 0; i < playernames.size(); i++) {
                document.writeStartElement("player");

                document.writeAttribute("playername",
                        String.valueOf(playernames.get(i)));
                document.writeAttribute("score", String.valueOf(scores.get(i)));

                document.writeEndElement();
            }

            document.writeEndElement();

            document.writeEndDocument();
        } catch (FileNotFoundException e) {
            System.err.println(highscorePath
                    + " konnte nicht geschrieben werden!");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                document.close();
            } catch (Exception e) {
                System.err.println("Dokument " + highscorePath
                        + " konnte nicht geschlossen werden.");
            }
        }

        if (Board.DEBUG) {
            System.out.println("XML Highscore erfolgreich geschrieben.");
        }
    }

    /**
     * Sets a new path than standard ("highscore.xml") for test uses only.
     * 
     * @param path path
     * 
     */
    public static void setHighscorePath(final String path) {
        highscorePath = path;
    }
    
    /**
     * Writes the statistic into xml file.
     * 
     * @param rocketCount rocketCount
     * @param rocketHitCount rocketHitCount
     */
    public static void writeStatisticsIntoXML(final int rocketCount,
            final int rocketHitCount) {
        XMLOutputFactory factory = XMLOutputFactory.newInstance();
        XMLStreamWriter document = null;

        if (Board.DEBUG) {
            System.out.println("XML Highscore (" + statisticsPath
                    + ") wird geschrieben.");
        }

        try {
            document = factory.createXMLStreamWriter(new FileOutputStream(
                    statisticsPath));

            document.writeStartDocument();

            document.writeStartElement("statistics");
            
                document.writeAttribute("rocketCount",
                        String.valueOf(rocketCount));
                document.writeAttribute("rocketHitCount",
                        String.valueOf(rocketHitCount));

            document.writeEndElement();

            document.writeEndDocument();
        } catch (FileNotFoundException e) {
            System.err.println(statisticsPath
                    + " konnte nicht geschrieben werden!");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                document.close();
            } catch (Exception e) {
                System.err.println("Dokument " + statisticsPath
                        + " konnte nicht geschlossen werden.");
            }
        }

        if (Board.DEBUG) {
            System.out.println("XML Statistic erfolgreich geschrieben.");
        }
    }
    
    /**
     * Writes a empty gamestate into xml file.
     */
    public static void writeEmptyGameStateIntoXML() {
        XMLOutputFactory factory = XMLOutputFactory.newInstance();
        XMLStreamWriter document = null;

        try {
            document = factory.createXMLStreamWriter(new FileOutputStream(
                    gameStatePath));

            document.writeStartDocument();

            document.writeStartElement("gamestate");

            document.writeEndElement();

            document.writeEndDocument();
        } catch (FileNotFoundException e) {
            System.err.println(gameStatePath
                    + " konnte nicht geschrieben werden!");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                document.close();
            } catch (Exception e) {
                System.err.println("Dokument " + gameStatePath
                        + " konnte nicht geschlossen werden.");
            }
        }

        if (Board.DEBUG) {
            System.out.println("XML GameState erfolgreich geleert.");
        }
    }
    
    /**
     * Writes the gamestate into xml file.
     * 
     * @param playername playername
     * @param points points
     * @param level level
     * @param cities cities
     */
    public static void writeGameStateIntoXML(final String playername,
            final int points, final int level, final ArrayList<City> cities) {
        XMLOutputFactory factory = XMLOutputFactory.newInstance();
        XMLStreamWriter document = null;

        if (Board.DEBUG) {
            System.out.println("XML GameState (" + gameStatePath
                    + ") wird geschrieben.");
        }

        try {
            document = factory.createXMLStreamWriter(new FileOutputStream(
                    gameStatePath));

            document.writeStartDocument();

            document.writeStartElement("gamestate");

                document.writeAttribute("playername", playername);
                document.writeAttribute("score", String.valueOf(points));
                document.writeAttribute("level", String.valueOf(level));
                
                for (int i = 0; i < cities.size(); i++) {
                    document.writeAttribute(("city_alive" + i),
                            String.valueOf(cities.get(i).isAlive()));
                }

            document.writeEndElement();

            document.writeEndDocument();
        } catch (FileNotFoundException e) {
            System.err.println(gameStatePath
                    + " konnte nicht geschrieben werden!");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                document.close();
            } catch (Exception e) {
                System.err.println("Dokument " + gameStatePath
                        + " konnte nicht geschlossen werden.");
            }
        }

        if (Board.DEBUG) {
            System.out.println("XML GameState erfolgreich geschrieben.");
        }
    }

    /**
     * writes the current content of levelcontroller.eventlist into a blank XML
     * file (can be used later to load new levels).
     * 
     * @param path
     *            path to xml file
     * @param eventList
     *            out of levelController, will be written into XML
     */
    public static void writeLevelIntoXML(final String path,
            final ArrayList<Event> eventList) {
        XMLOutputFactory factory = XMLOutputFactory.newInstance();
        XMLStreamWriter document = null;

        if (Board.DEBUG) {
            System.out.println("XML Datei (" + path + ") wird geschrieben.");
        }

        try {
            document = factory
                    .createXMLStreamWriter(new FileOutputStream(path));

            document.writeStartDocument();

            document.writeStartElement("levels");
            document.writeStartElement("events");

            for (int i = 0; i < eventList.size(); i++) {
                Event event = eventList.get(i);

                document.writeStartElement("event");

                document.writeAttribute("triggertime",
                        String.valueOf(event.getTriggerTime()));
                document.writeAttribute("eventtype", event.getEventType()
                        .toString());

                if (event.hasArgument()) {
                    document.writeAttribute("argument",
                            String.valueOf(event.getArgument()));
                }

                document.writeEndElement();
            }

            document.writeEndElement();
            document.writeEndElement();

            document.writeEndDocument();
        } catch (FileNotFoundException e) {
            System.err.println(path + "konnte nicht geschrieben werden!");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                document.close();
            } catch (Exception e) {
                System.err.println("Dokument " + path
                        + " konnte nicht geschlossen werden.");
            }
        }

        if (Board.DEBUG) {
            System.out.println("XML erfolgreich geschrieben.");
        }
    }
 
}
